﻿using System;
using System.Collections.Generic;
using System.IO;

namespace CssCommonLibrary
{
    public class CssFileController
    {
        private const string commentStart = @"/*";
        private const string commentEnd = @"*/";
        private const string paranthesisStart = @"{";
        private const string paranthesisEnd = @"}";


        private CssStack CStack { get; set; }
        public CssNodeList CssNodes { get; set; }

        public CssFileController(string filePath)
        {
            string[] lines = File.ReadAllLines(filePath);
            CssNodes = new CssNodeList();
            CStack = new CssStack();
            ParseClasses(Obfuscate(lines));
        }

        public override string ToString()
        {
            return CssNodes.ToString();
        }

        private string Obfuscate(string[] lines)
        {
            string cacheLine = String.Empty;
            foreach (string line in lines)
            {
                string tempLine = line;
                if (!String.IsNullOrWhiteSpace(tempLine))
                    tempLine = line.Trim();
                if (IsUnnecessary(tempLine))
                    continue;
                cacheLine += line.Trim();
            }
            return cacheLine;
        }

        private void ParseClasses(string obfuscatedLine)
        {
            string tempLine = obfuscatedLine;
            int i1, i2;
            while (!String.IsNullOrEmpty(tempLine))
            {
                i1 = tempLine.IndexOf(paranthesisStart);
                i2 = tempLine.IndexOf(paranthesisEnd);
                if (i2 < i1)
                    break;

                string selector = tempLine.Substring(0, i1).Trim();
                string content = tempLine.Substring(i1, i2 - i1 + 1);
                this.CssNodes.Add(new CssClassNode(selector, ParseClassContent(content)));
                tempLine = tempLine.Remove(0, i2 + 1);
            }
        }

        private List<CssProperty> ParseClassContent(string content)
        {
            content = content.Trim().Trim(new char[] { '{', '}' });
            List<CssProperty> contentProperties = new List<CssProperty>();
            string[] properties = content.Split(new char[] { ';' }, StringSplitOptions.RemoveEmptyEntries);
            foreach (string property in properties)
            {
                CssProperty p = ParseProperty(property);
                if (p == null)
                    continue;
                contentProperties.Add(p);
            }
            return contentProperties;
        }

        private CssProperty ParseProperty(string property)
        {
            string[] pair = property.Split(new char[] { ':' }, StringSplitOptions.RemoveEmptyEntries);
            if (pair.Length == 2)
                return new CssProperty(pair[0], pair[1]);
            return null;
        }

        private bool IsUnnecessary(string line)
        {
            if (String.IsNullOrWhiteSpace(line) || line.StartsWith(@"@"))
                return true;
            if (CStack.HasComment)
            {
                if (line.Contains(commentEnd))
                {
                    CStack.Pop();
                }
                return true;

            }
            else if (line.StartsWith(commentStart))
            {
                if (line.Contains(commentEnd))
                    return true;
                CStack.PushComment();
                return true;
            }
            return false;
        }
    }
}
